package com.hilinos.base.app.impl;

import java.util.ArrayList;
import java.util.List;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.hilinos.base.api.vo.AccountAddVo;
import com.hilinos.base.api.vo.UserVo;
import com.hilinos.base.app.UserApp;
import com.hilinos.base.common.config.ServerConfig;
import com.hilinos.base.service.KeyInfoService;
import com.hilinos.base.service.UserAccountService;
import com.hilinos.base.service.UserInfoService;
import com.hilinos.base.user.entity.pojo.UserAccountPoJo;
import com.hilinos.base.user.entity.pojo.UserInfoPoJo;
import com.hilinos.base.user.entity.vo.UserLoginVo;
import com.hilinos.common.common.ReturnCode;
import com.hilinos.common.entity.BaseQo;
import com.hilinos.common.util.AssertUtils;
import com.hilinos.common.util.ServletUtils;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;

@Component
public class UserAppImpl implements UserApp {

    @Autowired
    private UserAccountService userAccountService;

    @Autowired
    private UserInfoService userInfoService;

    @Autowired
    private ServerConfig serverConfig;

    @Autowired
    private KeyInfoService keyInfoService;

    @Override
    public void addUser(UserVo userVo) {
        // 保存用户信息
        userInfoService.save(UserInfoPoJo.builder()
                .appid(userVo.getAppid())
                .userId(userVo.getUserId())
                .userMobile(userVo.getUserMobile())
                .userDisplayName(userVo.getUserDisplayName())
                .userType(userVo.getUserType())
                .orgId(userVo.getOrgId())
                .deptId(userVo.getDeptId())
                .build());
    }

    @Override
    public void bindAccount(AccountAddVo accountVo) {
        // 保存账号信息
        UserAccountPoJo userAccountPoJo = UserAccountPoJo.builder()
                .userId(accountVo.getUserId())
                .appid(accountVo.getAccountType())
                .accountId(accountVo.getAccountId())
                .accountSecret(accountVo.getAccountSecret())
                .accountSecretExtra(accountVo.getAccountSecretExtra())
                .accountType(accountVo.getAccountType())
                .accountExpTime(accountVo.getAccountExpTime())
                .accountStatus(accountVo.getAccountStatus())
                .build();
        userAccountService.save(userAccountPoJo);
    }

    @Override
    public UserLoginVo login(String appid, String userType, String accountId, String accountPassword,
            String accountType, String orgId) {
        // 验证账号是否存在
        // 不根据机构查询
        UserAccountPoJo userAccount = null;
        if (ObjectUtils.isEmpty(orgId)) {
            List<UserAccountPoJo> userAccounts = userAccountService.getListByAccountId(accountId, accountType, appid);

            List<UserAccountPoJo> passwordSuccessedAccounts = new ArrayList<>();
            AssertUtils.isNotEmpty(userAccounts, ReturnCode.AUTH_USER_NOT_EXIST);
            for (UserAccountPoJo userTemp : userAccounts) {
                // 验证账号密码
                if (userTemp.checkPasswordByMD5(accountPassword.toUpperCase(), userTemp.getAccountSecretExtra())) {
                    passwordSuccessedAccounts.add(userTemp);
                }
            }
            AssertUtils.isNotEmpty(passwordSuccessedAccounts, ReturnCode.AUTH_ACCOUNT_PASSWORD_ERROR);
            AssertUtils.isRex(passwordSuccessedAccounts.size() == 1,
                    ReturnCode.AUTH_MULTI_USER.respMsg("查询到多个机构都存在该账号"));
            userAccount = passwordSuccessedAccounts.get(0);
        } else {
            // 使用机构查询
            userAccount = userAccountService.getDetail(accountId, accountType, orgId, appid);
            AssertUtils.isNotEmpty(userAccount, ReturnCode.AUTH_USER_NOT_EXIST);
            userAccount.checkPasswordByMD5(accountPassword.toUpperCase(),
                    userAccount.getAccountSecretExtra());
        }

        // 验证用户是否存在
        UserInfoPoJo userInfoPoJo = userInfoService.getDetail(userAccount.getUserId(), userType, appid);
        AssertUtils.isNotEmpty(userInfoPoJo, ReturnCode.AUTH_USER_NOT_EXIST);

        // 生成token
        String token = userInfoService.genToken(userInfoPoJo);

        // 保存token
        userInfoService.saveToken(userInfoPoJo, token, serverConfig.getTokenExpireTime());

        // 获取token信息,并返回用户信息和token信息
        UserLoginVo userLoginResult = UserLoginVo.builder().tokenInfo(userInfoService.getTokenInfo(token))
                .userInfo(userInfoPoJo).build();
        return userLoginResult;
    }

    @Override
    public UserLoginVo checkToken(String token) {
        return UserLoginVo.builder().tokenInfo(userInfoService.getTokenInfo(token))
                .userInfo(userInfoService.checkToken(token)).build();
    }

    @Override
    public void removeToken(String token) {
        userInfoService.removeToken(token);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void addUserAndAccount(UserVo userVo, AccountAddVo accountVo) {
        // 保存用户信息
        addUser(userVo);
        bindAccount(accountVo);
    }

    @Override
    public void editUser(UserVo userVo) {
        if (ObjectUtils.isEmpty(userVo.getAppid()) || !keyInfoService.isAdmin(ServletUtils.getAppid())) {
            userVo.setAppid(ServletUtils.getAppid());
        }
        userInfoService.editUser(UserInfoPoJo.builder()
                .userId(userVo.getUserId())
                .userMobile(userVo.getUserMobile())
                .userDisplayName(userVo.getUserDisplayName())
                .userType(userVo.getUserType())
                .build());
    }

    @Override
    public IPage<UserInfoPoJo> userPageList(BaseQo<UserInfoPoJo, UserVo, UserVo> userQo) {
        return userInfoService.page(userQo.page(), userQo.queryWrapper());
    }

}
